Java IDL:一時ネームサービス - tnameserv


このドキュメントでは、Java IDL 一時ネームサービス tnameserv の使用方法について説明します。Java IDL には、Object Request Broker Daemon (ORBD) も含まれています。ORBD は、ブートストラップサービス、一時ネームサービス、持続ネームサービス、およびサーバーマネージャーを含むデーモンプロセスです。Java IDL のすべてのチュートリアルでは ORBD を使用していますが、一時ネームサービスを使用する例では、orbd の代わりに tnameserv を使用できます。orbd ツールの詳細については、orbdマニュアルページまたはORBD に含まれる Java IDL ネームサービスに関するトピックを参照してください。

ここでは、以下の項目について説明します。

Java IDL 一時ネームサービス

CORBA の COS (Common Object Services) ネームサービスは、ファイルシステムがファイルに対してディレクトリ構造を提供しているのと同じように、オブジェクト参照に対してツリー構造のディレクトリを提供します。Java IDL の一時ネームサービスである tnameserv は、COS ネームサービスの仕様を単純な形で実装したものです。

オブジェクト参照は名前空間に名前で格納され、オブジェクト参照と名前のペアは、それぞれ「ネームバインディング」と呼ばれます。ネームバインディングは「ネーミングコンテキスト」に組み込むことができます。ネーミングコンテキストはそれ自体がネームバインディングであり、ファイルシステムのサブディレクトリと同じ編成機能を持ちます。すべてのバインディングは「初期ネーミングコンテキスト」に格納されます。名前空間において、初期ネーミングコンテキストは唯一の持続的バインディングです。 それ以外のネーミングコンテキストは、Java IDL のネーミングサービスプロセスが停止し、再起動されると失われます。

アプレットまたはアプリケーションから COS ネームサービスを使用するためには、その ORB はネームサービスが動作しているホストのポートを知っているか、そのネームサービスの文字列化された初期ネーミングコンテキストにアクセスできなければなりません。ネームサービスは、Java IDL のネームサービスでもその他の COS 準拠のネームサービスでもかまいません。

Java IDL 一時ネームサービスの起動

Java IDL ネームサービスは、ネームサービスを使用するアプリケーションまたはアプレットより前に起動しておかなければなりません。Java IDL 製品をインストールすると、Java IDL ネームサービスを起動するスクリプト (Solaris: tnameserv) か、実行可能ファイル (Windows NT: tnameserv.exe) が作成されます。バックグラウンドで動作するように、ネームサービスを起動してください。

特に指定しない場合、Java IDL ネームサービスは、ORB の resolve_initial_references() メソッドと list_initial_references() メソッドの実装に使用するブートストラッププロトコルに対してポート 900 で待機します。

	tnameserv -ORBInitialPort nameserverport&

ネームサーバーポートを指定しない場合、デフォルトでポート 900 が使用されます。Solaris ソフトウェアの実行時は、1024 より小さいポートでプロセスを開始する場合、root ユーザーになる必要があります。 このため、1024 または 1024 より大きいポートを使用することをお勧めします。 1050 のように別のポートを指定し、ネームサービスをバックグラウンドで実行するには、UNIX コマンドシェルで次のように入力します。

	tnameserv -ORBInitialPort 1050&

Windows の MS-DOS システムプロンプトでは、次のように入力します。

	start tnameserv -ORBInitialPort 1050

ネームサーバーのクライアントには、新しいポート番号を知らせる必要があります。このため、ORB オブジェクトの作成時に org.omg.CORBA.ORBInitialPort プロパティーに新しいポート番号を設定します。

異なるマシン上でのクライアントとサーバーの実行

Java IDL と RMI-IIOP のほとんどのチュートリアルでは、ネームサービス、サーバー、およびクライアントはすべて開発用のマシン上で実行されます。実際に配備する場合には、クライアントとサーバーを、ネームサービスとは異なるホスト上で実行することが多くなります。

クライアントとサーバーがネームサービスを見つけるには、クライアントとサーバーが、ネームサービスが実行されているポートの番号とホストを認識している必要があります。そのためには、クライアントとサーバーのファイル内の org.omg.CORBA.ORBInitialPort プロパティーと org.omg.CORBA.ORBInitialHost プロパティーをネームサービスが実行されているポートの番号とマシンの名前に設定します。この例は、「RMI-IIOP を使った Hello World の例」に示されています。コマンド行オプション -ORBInitialPort nameserverport#-ORBInitialHost nameserverhostname を使用して、クライアントとサーバーに対してネームサービスを探す場所を指定することもできます。「Java IDL: 2 台のマシン上で実行する Hello World プログラム」 には、コマンド行オプションを使用して指定する方法が示されています。

たとえば、一時ネームサービス tnameserv が、ホスト nameserverhost のポート 1050 上で実行されているとします。さらに、クライアントがホスト clienthost 上で実行され、サーバーはホスト serverhost 上で実行されているとします。

-J オプション

このコマンド行オプションは、tnameserve とともに使用できます。
-Joption
Java 仮想マシンに option を渡します。 option には、「Java アプリケーション起動ツール」のリファレンスページに記載されているオプションを 1 つ指定します。たとえば、-J-Xms48m と指定すると、スタートアップメモリーは 48M バイトに設定されます。-J を使って背後の実行環境にオプションを渡すことはよく行われています。

Java IDL 一時ネームサービスの停止

Java IDL ネームサービスを停止するには、Unix の場合は、kill などのオペレーティングシステムのコマンドを使い、Windows の場合は、Ctrl-C を使います。ネームサービスを明示的に停止するまでは、呼び出し待機状態が続きます。なお、サービスを終了させると、Java IDL ネームサービスに登録されている名前は失われます。

サンプルクライアント:名前空間へのオブジェクトの追加

次に示すサンプルプログラムは、名前を名前空間に追加する方法を示すものです。このサンプルプログラムは、このままの状態で完全に動作する一時ネームサービスクライアントで、次のような単純なツリーを作成するものです。


                  初期
               ネーミングコンテキスト
                  /      \
                 /        \
              plans     Personal
                         /   \
                        /     \
                   calendar  schedule

この例で、plans はオブジェクト参照、Personalcalendarschedule の 2 つのオブジェクト参照を含むネーミングコンテキストです。

import java.util.Properties;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class NameClient
{
   public static void main(String args[])
   {
      try {
前述の「Java IDL 一時ネームサービスの起動」で、ネームサーバーはポート 1050 を使用して起動しました。 次のコードで、このポート番号をクライアントプログラムに知らせます。
        Properties props = new Properties();
        props.put("org.omg.CORBA.ORBInitialPort", "1050");
        ORB orb = ORB.init(args, props);

次のコードでは、初期ネーミングコンテキストを取得し、それを ctx に代入します。2 行目では、ctx をダミーのオブジェクト参照 objref にコピーします。 この objref には、あとでさまざまな名前を割り当てて名前空間に追加します。
        NamingContext ctx =
NamingContextHelper.narrow(orb.resolve_initial_references("NameService"));
        NamingContext objref = ctx;

次のコードでは、text 型の名前 plans を作成し、それをダミーのオブジェクト参照にバインドします。その後、rebind を使用して初期ネーミングコンテキストの下に "plans" を追加しています。rebind メソッドを使用すれば、bind を使用した場合に発生する例外を発生させずに、このプログラムを何度も繰り返し実行できます。
        NameComponent nc1 = new NameComponent("plans", "text");
        NameComponent[] name1 = {nc1};
        ctx.rebind(name1, objref);
        System.out.println("plans rebind sucessful!");

次のコードでは、directory 型の Personal というネーミングコンテキストを作成します。その結果得られるオブジェクト参照 ctx2 をこの名前にバインドし、初期ネーミングコンテキストに追加します。
        NameComponent nc2 = new NameComponent("Personal", "directory");
        NameComponent[] name2 = {nc2};
        NamingContext ctx2 = ctx.bind_new_context(name2);
        System.out.println("new naming context added..");

残りのコードでは、ダミーのオブジェクト参照を schedule と calendar という名前でネーミングコンテキスト "Personal" (ctx2) にバインドします。
        NameComponent nc3 = new NameComponent("schedule", "text");
        NameComponent[] name3 = {nc3};
        ctx2.rebind(name3, objref);
        System.out.println("schedule rebind sucessful!");

        NameComponent nc4 = new NameComponent("calender", "text");
        NameComponent[] name4 = {nc4};
        ctx2.rebind(name4, objref);
        System.out.println("calender rebind sucessful!");


    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
  }
}

サンプルクライアント:名前空間のブラウズ

次のサンプルプログラムでは、名前空間をブラウズする方法を示します。

import java.util.Properties;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class NameClientList
{
   public static void main(String args[])
   {
      try {
前述の「Java IDL 一時ネームサービスの起動」で、ネームサーバーはポート 1050 を使用して起動しました。 次のコードで、このポート番号をクライアントプログラムに知らせます。

        Properties props = new Properties();
        props.put("org.omg.CORBA.ORBInitialPort", "1050");
        ORB orb = ORB.init(args, props);


次のコードでは、初期ネーミングコンテキストを取得しています。
        NamingContext nc =
NamingContextHelper.narrow(orb.resolve_initial_references("NameService"));

list メソッドは、ネーミングコンテキストに追加されているバインディングをリストします。この場合、最大 1000 個までのバインディングが初期ネーミングコンテキストから BindingListHolder に返されます。 残りのバインディングは、BindingIteratorHolder に返されます。
        BindingListHolder bl = new BindingListHolder();
        BindingIteratorHolder blIt= new BindingIteratorHolder();
        nc.list(1000, bl, blIt);

次のコードでは、返された BindingListHolder からバインディングの配列を取得します。バインディングがない場合は、プログラムは終了します。
        Binding bindings[] = bl.value;
        if (bindings.length == 0) return;

残りのコードでは、バインディングに対してループ処理を行い、名前を出力します。
        for (int i=0; i < bindings.length; i++) {

            // get the object reference for each binding
            org.omg.CORBA.Object obj = nc.resolve(bindings[i].binding_name);
            String objStr = orb.object_to_string(obj);
            int lastIx = bindings[i].binding_name.length-1;

            // check to see if this is a naming context
            if (bindings[i].binding_type == BindingType.ncontext) {
              System.out.println( "Context: " +
bindings[i].binding_name[lastIx].id);
            } else {
                System.out.println("Object: " +
bindings[i].binding_name[lastIx].id);
            }
        }

       } catch (Exception e) {
        e.printStackTrace(System.err);
       }
   }
}

Copyright © 2006 Sun Microsystems, Inc. All Rights Reserved.

Sun
Java Software